#include "datacollection.hpp"
#include <sstream>
#include <iostream>
#include <boost/regex.hpp>
#include <cmath>
using std::stringstream;
using namespace com_oocl_monitor::domain;
using std::endl;

Node::Node(const string & dateTime, const size_t& size)
//    :_dateTime(dateTime), _size(size)
	:_size(size)
{
	if (dateTime != "")
		_dateTime = boost::posix_time::ptime(boost::posix_time::time_from_string(dateTime));
}

//文件大小影响
bool Node::operator==(const Node& right)
{
	//ignore the file size
//    if(_size==right._size)
//        return true;
//    else{
//        double diff=fabs(_size-right._size);
//        diff=diff/(_size>right._size?_size:right._size);
//        if(diff<0.1)
//            return true;
//    }
//    return false;
	return true;
}
bool Node::operator==(const Node& right) const
{
	//ignore the file size
//    if(_size==right._size)
//        return true;
//    else{
//        double diff=fabs(_size-right._size);
//        diff=diff/(_size>right._size?_size:right._size);
//        if(diff<0.1)
//            return true;
//    }
//    return false;
	return true;
}
DataCollection::DataCollection(const string& regexPattern)
	:_regexPattern(regexPattern)
{
}

DataCollection::~DataCollection()
{
}

bool DataCollection::isEmpty() const
{
	return _dataSet.empty();
}

void DataCollection::insert(const DataPair &pair) {
	//    _dataSet->insert(pair);
	insert(pair.first, pair.second);
}

void DataCollection::insert(const KeyType & key, const ValueType & value)
{
	string fileName = key;
	if (!_regexPattern.empty()) {
		boost::cmatch res;
		boost::regex reg(_regexPattern.c_str());
		if (boost::regex_search(fileName.c_str(), res, reg)) {
			fileName = res[0];
		}
	}
	_dataSet.insert(pair<KeyType, ValueType>(fileName, value));
}

void DataCollection::erase(const KeyType & key)
{
	_dataSet.erase(key);
}

void DataCollection::clear()
{
	_dataSet.clear();
}

size_t DataCollection::size() const
{
	return _dataSet.size();
}


ValueType & DataCollection::operator[](const KeyType &key)
{
	return _dataSet.at(key);
}

const ValueType & DataCollection::operator[](const KeyType& key) const
{
	return _dataSet.at(key);
}

string DataCollection::toString() const
{
	string result;
	stringstream ss;
	for (map<KeyType, ValueType>::const_iterator it = _dataSet.cbegin(); it != _dataSet.cend(); ++it)
	{
		string tmp;
		ss << it->first << " ";
		ss << it->second._dateTime << " ";
		ss << it->second._size;
		ss << endl;
		getline(ss, tmp);
		result += tmp + "\r\n ";
	}
	return result;
}

DataCollection *DataCollection::clone() const {
	DataCollection *cp = new DataCollection;
	cp->_dataSet.insert(_dataSet.cbegin(), _dataSet.cend());
	cp->_regexPattern = this->_regexPattern;
	return cp;
}

namespace com_oocl_monitor {
	namespace domain {
		DataCollection* operator-(const DataCollection &left, const DataCollection &right)
		{
			DataCollection* result = new DataCollection;
			if (&left == &right)
				return result;
			for (auto it = left._dataSet.cbegin(); it != left._dataSet.cend(); ++it)
			{
				auto f = right._dataSet.find(it->first);
				if (f != right._dataSet.end() && f->second == it->second) {
					continue;
				}
				result->insert(it->first, it->second);
			}
			return result;
		}
		DataCollection* operator+(const DataCollection& left, const DataCollection& right) {
			DataCollection *result = new DataCollection;
			result->_dataSet.insert(left._dataSet.begin(), left._dataSet.end());
			result->_dataSet.insert(right._dataSet.begin(), right._dataSet.end());
			return result;
		}
	}
}

